this
and closureswindow
and document
, that represent a client-side web application and all HTML elements
are visible in JS code.
window
and document
, be used?var p = 10; ... var p = 15; alert(p);
window
object as a property.obj.property_name
or obj['property_name']
obj.method_name(...)
or obj['method_name'](...)
let property_name = ...; let property_value = ...; obj[property_name] = property_value;
let method_name = ...; let method_code = ...; obj[method_name] = method_code; obj[method_name](...);
// These are both globals. var foo = 1; // This variable with 'var' will be created in the 'window' object as a property. // If the property exists, it will be overwritten. Need to be careful. bar = 2; // Same as above function test_scope() { var foo = 1; // Local bar = 3; // Global // Execute an anonymous function. Isn't it interesting? (function() { var wibble = 1; // Local foo = 2; // Inherits from the scope above (creating a closure) moo = 3; // Global })(); } test_scope();
window
data[anyindex] = ...;
person[2] = 'Dave';
.
What do you see?
Array.isArray(data)
for...in
and for...of
delete person.age;
var x = {}; Object.defineProperty(x, "p", { value : 3, writable: true, enumerable: false, configurable: true}); Object.defineProperty(x, "p", { writable: false} ); alert(Object.getOwnPropertyDescriptor(x, "p").writable); // .getOwnPropertyDescriptor() returns {vale:..., writable:..., enumerable:..., configurable:...}.
function Apple (type) { // This is similar to the definition of a class in Java. // The keyword is function, not class. // A function is a constructor that is instantiated later. this.type = type; // this.type: global; type: local this.color = "red"; this.getInfo = function() { return this.color + ' ' + this.type + ' apple'; }; }; var apple = new Apple('macintosh'); // keyword 'new' to create an object apple.color = "reddish"; alert(apple.getInfo()); //----------------------------------------------------------- function Car (type, color) { this.type = type; this.color = color; }; var passat = new Car('passenger', 'black'); Car.prototype.size = 'small'; Car.prototype.getInfo = function() { // Car.prototype return this.color + ' ' + this.type + ' car'; }; var golf = new Car('passenger', 'silver'); alert(golf.getInfo()); alert(passat.getInfo()); // ???
var apple = new function() { this.type = "macintosh"; this.getInfo = function () { return this.color + ' ' + this.type + ' apple'; }; } apple.color = "reddish"; alert(apple.getInfo());
var o = {}; // or var o = new Object(); // for arrays var a = []; // or var a = new Array(); //----------------------------------------------------------- var apple = { // In this case you cannot create another instance of the class later. type: "macintosh", color: "red", getInfo: function () { return this.color + ' ' + this.type + ' apple'; } } apple.color = "reddish"; alert(apple.getInfo()); //----------------------------------------------------------- var apple = {}; apple.type = 'Gala'; // Not apple.prototype.type. Why? apple.color = 'Red'; apple.getInfo = function () { return this.color + ' ' + this.type + ' apple'; }; alert(apple.getInfo());
$trujs
and $trujs._expressions
with its value.
The property name is given with a user-defined attribute 'trujs-model'.
function fruit(type) { if (type == "GoldenDelicious") return { type: "GoldenDelicious", color: "yellow", getInfo: function () { return this.color + ' ' + this.type + ' apple'; } } else if (type == "PinkLady") return { type: "PinkLady", color: "pink", getInfo: function () { return this.color + ' ' + this.type + ' apple'; } } else return { type: "Unknown"; } } var apple = fruit("GoldenDelicious"); alert(apple.getInfo);
$trujq
function that has a paramter of CSS selector and returns an object.
The returned object needs to have the method click()
that responses to the click event on the HTML elements that are selected with the passed CSS selector.
const person = (function(n, a) { // What value does person have? function() { ... or the returned function? // What is (function() { ... })()? Function invocation? let name = n; let age = a; return { // What kind of data is returned? first_name: name, get_name: function() { return name; }, // NOT this.name set_name: function(new_name) { name = new_name; }, get_age: function() { return age; }, // NOT this.age set_age: function(new_age) { age = new_age; } }; })('Tim', 22); alert(person.age); // undefined; why??? person.name = 'Gildong'; // This name is not the private variable name. Why??? alert(person.first_name); // 'Tim' person.first_name = 'Gildong'; // This first_name is the public variable first_name. alert(person.first_name); // 'Gildong'; It does not change the private variable. alert(person.get_name()); // 'Tim' alert(person.get_age()); person.set_age(24); alert(person.get_age());
Student
function using the above Module pattern.
The object returned from Student
needs to keep private name
and id
.
The object has setName()
, getName()
, setId()
, and getId()
methods to access them.
$trujq
function that has a parameter of CSS selector and returns an object.
The returned object needs to have the method click()
that responses to the click event on the selected HTML elements with the passed CSS selector.
Note that the click()
method has a parameter of function which will be invoked in a click event listener.
$trujq
function that has a parameter of CSS selector and returns an object.
The returned object needs to have the method each()
that goes through each selected HTML element.
Note that the each()
method has a parameter of function which will be invoked in each()
.
n
numbers, adds them and returns the result using a callback function.
this
keyword and functions, especially with callback functionsthis
.<script> function printType(msg, x) { if (x == window) alert(msg + ": " + 'window'); else if (x == document) alert(msg + ": " + 'document'); else if (x instanceof HTMLElement) alert(msg + ": " + 'HTMLElement ' + x.id); else alert(msg + ": " + 'something else'); } function foo() { printType("foo-this", this); // what is this? } function goo(obj, callback) { printType("goo-this", this); // what is this? foo(); printType("goo-obj", obj); // what is obj? callback(); // check 'this' in callback() carefully. // a very important trick; There is another way and we will see it later. obj.__TRUjQ__callback = callback; obj.__TRUjQ__callback(); // check 'this' in callback() carefully. } $('#tr1-button').click(function() { printType("button-click-this", this); // what is this? let this_button = this; goo(this, function() { printType("goo-callback-this", this); // what is this? printType("goo-callback-this_button", this_button); }); }); foo(); </script> <p id='tr1-p'>Interesting!</p> <button id='tr1-button'>Click me!</button>
event listener for the click over the button: // It is defined on the button HTMLElement object. alert() with this; goo(this, callback): // goo is defined in ???. alert() with this; foo(): // foo is defined in ???. alert() with this; alert() with the passed argument; callback(): // Where is it defined? alert() with this; alert() with this_button; obj.__TRUjQ__callback(): alert() with this; alert() with this_button;
var
and let
work differently. What will be printed?
<script> function foo(lists) { let fts = []; for (let i = 0; i < lists.length; i++) { var p = lists[i]; // what if 'let' is used instead of 'var'? fts[i] = function() { alert(p); // p cannot be destroyed at the end of each for-iteration. // what if 'lists[i]' is used instead of 'p'? }; } return fts; // array of functions } function goo() { let lists = [1, 2, 3]; let fts = foo(lists); for (let i = 0; i < fts.length; i++) fts[i](); // What will be printed? 1, 2, and 3? } $('#tr2-button').click(function() { goo(); }); </script> <button id='tr2-button'>Click me to test the above code!</button>
let p = lists[i];
.
var p
, but 1, 2, and 3 with let p
.
When this function is called, p
is evaluated and it will be 3, 3, and 3.